<?php
class TbfChineseNumber {
    //一个字符一个字符把数字转换成汉字表示如 2004 -> 二零零四
    //忽略不能处理的字符,认为num是整数
    static function DigestToChineseNumberByChar($num){
        $char = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
        $num = $num.'';
        $len = strlen($num);
        $output = '';
        for ($i=0;$i<$len;$i++){
            $c = ord($num[$i])-ord('0');
            if ($c<0||$c>=10){
                continue;
            }
            $output.=$char[$c];
        }
        return $output;
    }
    //把数字表示转换成中文大写数字表示 如 2004 -> 贰千零肆
    static function NumToBiggerChineseNumber($num){
        $char = array('零','壹','贰','叁','肆','伍','陆','柒','捌','玖');
        $unit1 = array('拾', '佰', '仟');
        $unit2 = array('萬', '億', '兆');
        return self::innerNumToChineseNumber($num,$char,$unit1,$unit2);
    }

    //把数字表示转换成中文大写数字表示 如 2004 -> 二千零四
    static function NumToChineseNumber($num){
        $char = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
        $unit1 = array('十', '百', '千');
        $unit2 = array('万', '亿', '兆');
        return self::innerNumToChineseNumber($num,$char,$unit1,$unit2);
    }

    private static function innerNumToChineseNumber($num,$char,$unit1,$unit2){
        $num = (int)floor($num);
        if ($num==0){
            return $char[0];
        }
        $num = $num.'';
        $len = strlen($num);
        $output = '';
        $hasNumBefore = false; //之前是否写出过数字
        $hasCrossZero = false; //之前是否全零
        if ($len>12){ //兆
            //超过1兆的部分不做处理
            $output = substr($num,0,$len-12).$unit2[2];
            $num = substr($num,$len-12);
            $hasNumBefore = true;
            $len = strlen($num);
        }
        if ($len>8){ //亿
            $thisP1Num = substr($num,0,$len-8);
            if (((int)$thisP1Num)>0){
                $thisP1 = self::innerNumToChineseLessThan10000($thisP1Num,$char,$unit1);
                if ($hasNumBefore && $thisP1Num<1000){
                    $output .= $char[0];
                }
                $output .= $thisP1.$unit2[1];
                $hasCrossZero = false;
            }else{
                $hasCrossZero = true;
            }
            $num = substr($num,$len-8);
            $len = strlen($num);
            $hasNumBefore = true;
        }
        if ($len>4){ //万
            $thisP1Num = substr($num,0,$len-4);
            if (((int)$thisP1Num)>0){
                $thisP1 = self::innerNumToChineseLessThan10000($thisP1Num,$char,$unit1);
                if ($hasNumBefore && $thisP1Num<1000){
                    $output .= $char[0];
                }elseif ($hasCrossZero){
                    $output .= $char[0];
                }
                $output .= $thisP1.$unit2[0];
                $hasCrossZero = false;
            }else{
                $hasCrossZero = true;
            }
            $num = substr($num,$len-4);
            $hasNumBefore = true;
        }
        if (((int)$num)>0){
            $thisP1 = self::innerNumToChineseLessThan10000($num,$char,$unit1);
            if ($hasNumBefore && $num<1000){
                $output .= $char[0];
            }elseif ($hasCrossZero){
                $output .= $char[0];
            }
            $output .= $thisP1;
        }else{
            //如果是0要输出个零
            if (!$hasNumBefore){
                $output = $unit1[0];
            }
        }
        $output = str_replace($char[1].$unit1[0],$unit1[0],$output);
        return $output;
    }

    private static function innerNumToChineseLessThan10000($num,$char,$unit1){
        $output = '';
        $hasCrossZero = false;
        if ($num>=1000){
            $thisNum = (int)floor($num/1000);
            $output.=$char[$thisNum].$unit1[2];
            $hasCrossZero = false;
        }
        if ($num>=100){
            $thisNum = (int)floor($num/100%10);
            if ($thisNum>0){
                $output.=$char[$thisNum].$unit1[1];
                $hasCrossZero = false;
            }else{
                $hasCrossZero = true;
            }
        }
        if ($num>=10){
            $thisNum = (int)floor($num/10%10);
            if ($thisNum>0){
                if ($hasCrossZero){
                    $output.=$char[0];
                }
                $output.=$char[$thisNum].$unit1[0];
                $hasCrossZero = false;
            }else{
                $hasCrossZero = true;
            }
        }
        if ($num>=1){
            $thisNum = (int)floor($num%10);
            if ($thisNum>0){
                if ($hasCrossZero){
                    $output.=$char[0];
                }
                $output.=$char[$thisNum];
            }
        }
        if ($num==0){
            $output = $char[0];
        }
        return $output;
    }
} 